package com.eshipenet.shipnet.commplanrpc.grpc;

import com.eshipenet.shipnet.CommCard.grpc.*;
import com.eshipenet.shipnet.commplan.FindAllResult;
import com.eshipenet.shipnet.commplan.grpc.PageInfo;
import com.eshipenet.shipnet.commplanrpc.service.CommCardService;
import com.eshipenet.shipnet.commplanrpc.service.CommPlanIdGenerator;
import com.eshipenet.shipnet.commplanrpc.util.GetJObjectUtil;
import com.eshipenet.shipnet.commplanrpc.util.TimestampToDate;
import com.google.protobuf.Struct;
import io.grpc.stub.StreamObserver;
import org.json4s.JsonAST;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.Option;
import scala.collection.immutable.List;
import squirrel.JSONQuery;

import java.util.ArrayList;

public class CommCardRepoGrpcImpl extends CommCardRepoGrpc.CommCardRepoImplBase {
  private Logger              logger = LoggerFactory.getLogger("CommCardRepoGrpcImpl");
  private CommCardService     service;
  private CommPlanIdGenerator idGenerator;
  public CommCardRepoGrpcImpl(CommCardService service,CommPlanIdGenerator idGenerator) {
    this.service = service;
    this.idGenerator = idGenerator;
  }


  /**
   * 查询列表
   *
   * @param req
   * @param responseObserver
   */
  public void findAll(CommCardFindAllRequest req, StreamObserver<CommCardFindAllReply> responseObserver) {

    try {
      logger.info("CommCardRepoGrpcImpl.findAll.Filter    {}", req.getFilter());
      CommCardFindAllReply reply = findAllInner(req);
      responseObserver.onNext(reply);
      responseObserver.onCompleted();

    } catch (Exception e) {
      responseObserver.onError(e);
    }

  }


  /**
   * 创建
   *
   * @param req
   * @param responseObserver
   */
  public void createOne(CommCardCreateOneRequest req, StreamObserver<CommCardCreateOneReply> responseObserver) {
    try {
      logger.info("CommCardRepoGrpcImpl.createOne.data   {}", req.getData());
      CommCardCreateOneReply reply = createOneInner(req);
      responseObserver.onNext(reply);
      responseObserver.onCompleted();

    } catch (Exception e) {
      responseObserver.onError(e);
    }

  }

  /**
   * 修改
   *
   * @param req
   * @param responseObserver
   */
  public void updateOne(CommCardUpdateOneRequest req, StreamObserver<CommCardUpdateOneReply> responseObserver) {
    try {
      logger.info("CommCardRepoGrpcImpl.updateOne.data   {}", req.getData());
      CommCardUpdateOneReply reply = updateOneInner(req);
      responseObserver.onNext(reply);
      responseObserver.onCompleted();

    } catch (Exception e) {
      responseObserver.onError(e);
    }

  }


  /**
   * 删除
   *
   * @param req
   * @param responseObserver
   */
  public void deleteOne(CommCardDeleteOneRequest req, StreamObserver<CommCardDeleteOneReply> responseObserver) {
    try {
      logger.info("CommCardRepoGrpcImpl.deleteOne.id  {}", req.getId());
      CommCardDeleteOneReply reply = deleteOneInner(req);
      responseObserver.onNext(reply);
      responseObserver.onCompleted();

    } catch (Exception e) {
      responseObserver.onError(e);
    }

  }

  public CommCardFindAllReply findAllInner(CommCardFindAllRequest req) {

    int limit = req.getFilter().getLimit();
    int offset = req.getFilter().getOffset();

    if (limit == 0) {
      limit = 500;

    }
    if (offset == 0) {
      offset = 1;

    }

    //查询条件
    Struct wheres = req.getFilter().getWhere();

    JsonAST.JObject jObject = GetJObjectUtil.getWhere(wheres);

    //联合查询
    java.util.List<CommCardFindAllFilterInclude> in_list = req.getFilter().getIncludeList();

    ArrayList<JsonAST.JValue> arrayList = new ArrayList<>();

    for (CommCardFindAllFilterInclude include : in_list) {

      JsonAST.JValue jValue = new JsonAST.JString(include.getName());

      arrayList.add(jValue);

    }
    List<JsonAST.JValue> includes_list = scala.collection.JavaConverters.asScalaIterator(arrayList.iterator()).toList();

    JsonAST.JArray jArray = new JsonAST.JArray(includes_list);

    //生成查询列表的sql
    JSONQuery jsonQuery = JSONQuery.apply(new JsonAST.JString("CommCard"),
                                          Option.apply(jObject),
                                          Option.apply(new JsonAST.JString("*")),
                                          Option.apply(jArray),
                                          Option.apply(null),
                                          Option.apply(null));

    FindAllResult result = service.findAll(jsonQuery, limit, offset);
    //数据总数
    int totalCount = result.getTotalCount();
    //列表数据
    java.util.List<CommCardEdge> list = new ArrayList<>();
    //判断是否有数据，无数据时直接返回
    if (totalCount < 1) {
      //设置分页信息
      PageInfo pageInfo = PageInfo.newBuilder()
                                  .setHasNextPage(result.isHasNextPage())
                                  .setHasPreviousPage(result.isHasPreviousPage())
                                  .build();

      return CommCardFindAllReply.newBuilder()
                                 .setReq(req)
                                 .addAllEdges(list)
                                 .setPageInfo(pageInfo)
                                 .setTotalCount(0).build();
    }

    list = result.getList();

    //设置分页信息
    PageInfo pageInfo = PageInfo.newBuilder()
                                .setHasNextPage(result.isHasNextPage())
                                .setHasPreviousPage(result.isHasPreviousPage())
                                .setStartCursor(result.getStartCursor())
                                .setEndCursor(result.getEndCursor()).build();


    return CommCardFindAllReply.newBuilder()
                               .setReq(req)
                               .addAllEdges(list)
                               .setPageInfo(pageInfo)
                               .setTotalCount(totalCount).build();
  }


  public CommCardCreateOneReply createOneInner(CommCardCreateOneRequest req) {

    //获取当前时间
    java.sql.Timestamp createdAt = new java.sql.Timestamp(System.currentTimeMillis());

    Struct data = req.getData().getInfo();
    String data_str = GetJObjectUtil.getData(data);

    String key = idGenerator.generate();
    com.eshipenet.shipnet.commplan.CommCard commCard = new com.eshipenet.shipnet.commplan.CommCard(
      req.getData().getCardId(),
      req.getData().getKind(),
      req.getData().getName(),
      req.getData().getDescription(),
      req.getData().getAvatar(),
      createdAt,
      createdAt,
      data_str,
      req.getData().getStatus(),
      req.getData().getPlanId()
    );


    commCard = service.createOne(key,commCard);

    CommCard CommCardBuilder = CommCard.newBuilder()
                                       .setId(key)
                                       .setCardId(commCard.getCardId())
                                       .setPlanId(commCard.getPlanId())
                                       .setName(commCard.getName())
                                       .setDescription(commCard.getDescription())
                                       .setKind(commCard.getKind())
                                       .setAvatar(commCard.getAvatar())
                                       .setStatus(commCard.getStatus())
                                       .setCreatedAt(TimestampToDate.dateTotimestamp(commCard.getCreatedAt()))
                                       .setUpdatedAt(TimestampToDate.dateTotimestamp(commCard.getCreatedAt()))
                                       .setInfo(GetJObjectUtil.getData(commCard.getInfo()))
                                       .build();

    return CommCardCreateOneReply.newBuilder().setData(CommCardBuilder).setReq(req).build();


  }


  public CommCardUpdateOneReply updateOneInner(CommCardUpdateOneRequest req) {
    //获取当前时间
    java.sql.Timestamp updatedAt = new java.sql.Timestamp(System.currentTimeMillis());

    Struct data = req.getData().getInfo();
    String data_str = GetJObjectUtil.getData(data);
    com.eshipenet.shipnet.commplan.CommCard commCard = new com.eshipenet.shipnet.commplan.CommCard(
      req.getData().getCardId(),
      req.getData().getKind(),
      req.getData().getName(),
      req.getData().getDescription(),
      req.getData().getAvatar(),
      null,
      updatedAt,
      data_str,
      req.getData().getStatus(),
      req.getData().getPlanId()
    );

    commCard = service.updateOne(req.getData().getId(), commCard);

    CommCard CommCardBuilder = CommCard.newBuilder()
                                       .setId(req.getData().getId())
                                       .setCardId(commCard.getCardId())
                                       .setPlanId(commCard.getPlanId())
                                       .setName(commCard.getName())
                                       .setDescription(commCard.getDescription())
                                       .setKind(commCard.getKind())
                                       .setAvatar(commCard.getAvatar())
                                       .setStatus(commCard.getStatus())
                                       .setCreatedAt(TimestampToDate.dateTotimestamp(commCard.getCreatedAt()))
                                       .setUpdatedAt(TimestampToDate.dateTotimestamp(commCard.getCreatedAt()))
                                       .setInfo(GetJObjectUtil.getData(commCard.getInfo()))
                                       .build();

    return CommCardUpdateOneReply.newBuilder().setData(CommCardBuilder).setReq(req).build();


  }


  public CommCardDeleteOneReply deleteOneInner(CommCardDeleteOneRequest req) {

    com.eshipenet.shipnet.commplan.CommCard commCard = service.deleteOne(req.getId());

    CommCard CommCardBuilder = CommCard.newBuilder()
                                       .setId(req.getId())
                                       .setCardId(commCard.getCardId())
                                       .setPlanId(commCard.getPlanId())
                                       .setName(commCard.getName())
                                       .setDescription(commCard.getDescription())
                                       .setKind(commCard.getKind())
                                       .setAvatar(commCard.getAvatar())
                                       .setStatus(commCard.getStatus())
                                       .setCreatedAt(TimestampToDate.dateTotimestamp(commCard.getCreatedAt()))
                                       .setUpdatedAt(TimestampToDate.dateTotimestamp(commCard.getCreatedAt()))
                                       .setInfo(GetJObjectUtil.getData(commCard.getInfo()))
                                       .build();


    return CommCardDeleteOneReply.newBuilder().setData(CommCardBuilder).setReq(req).build();

  }

}

